﻿package ru.indee.ui.detectForm 
{
	import flash.geom.Point;
	import ru.indee.geom.line;
	
	/**
	 * ...
	 * @author Raidnew
	 */
	public class detectLogic 
	{
		
		private static function out(data:*):void {
			//output.out(data);
		}
		
		public function detectLogic() 
		{
			
		}
		
		private static function detectLine(form:objectForDetect):Boolean {
			out("Check LINE");
			
			var arrayDetect:Array = form.getPointsArray();
			
			var lengthEndPoints:Number = Point.distance(arrayDetect[0], arrayDetect[arrayDetect.length - 1]);
			
			var allowDelta:Number = form.getFullLengthForm() * settingLogic.lineCoeff;
			
			if((form.getFullLengthForm() - lengthEndPoints) < allowDelta){
			
			//if (form.getPointsArray().length == 2) {
				out("	true");
				return true;
			}
			else {
				out("	false");
				return false;
			}
		}
		
		private static function detectTriangle(form:objectForDetect):Boolean {
			out("Check TRIANGLE");
			if ((processingForm.detectCloseForm(form)) && (form.getPointsArray().length == 4)) {
				out("	true");
				return true;
			}else if ((processingForm.detectCloseForm(form)) && (form.getPointsArray().length == 5)) {
				out("	alternative step 1 true");
				
				if (form.getAngleStartFinishLine() < (form.getAverageAngle() * settingLogic.finishAngleProportion)) {
					out("	true");
					return true;
				}else {
					out("	false");
					return false;
				}
			}else {
				out("	false");
				return false;
			}
		}
		
		private static function detectSquare(form:objectForDetect):Boolean {
			out("Check SQUARE");
			if ((processingForm.detectCloseForm(form)) && (form.getPointsArray().length == 5)) {
				
				out("	step1 true");
				
				var arrAngle:Array = form.getAngleArray();
				var detectError:Boolean = false;
				
				for (var i:Number = 1; i < arrAngle.length; i++ ) {
					if (((arrAngle[0] < 0) && (arrAngle[i] < 0)) || ((arrAngle[0] > 0) && (arrAngle[i] > 0))) {
						
					}else {
						detectError = true;
						break;
					}
				}
				
				if (!detectError) {
					out("	true");	
					return true;
				}else {
					out("	false");	
					return false;
				}
				
			}else if ((processingForm.detectCloseForm(form)) && (form.getPointsArray().length == 6)) {
				out("	alternative step 1 true");
				if (form.getAngleStartFinishLine() < form.getAverageAngle() * settingLogic.finishAngleProportion) {
					out("	true");
					return true;
				}else {
					out("	false");
					return false;
				}
			}else {
				out("	false");
				return false;
			}
		}
		
		private static function detectW(form:objectForDetect):Boolean {
			
			out("Check LETTER_W");
			
			if (processingForm.detectCloseForm(form)) {
				out("	false");
				return false;
			}
			
			out("	step1 true");
			var arrAngles:Array = form.getAngleArray();
			
			if (arrAngles.length != 3) {
				out("	false");
				return false;
			}
						
			out("	step2 true");
			var errorDetect:Boolean = false;
			
			var lastAngle:Number = 0;
			
			for (var i:Number = 1; i < arrAngles.length; i++) {
				
				if((arrAngles[i-1] < 0)&&(arrAngles[i] > 0)){
				}else if((arrAngles[i-1] > 0)&&(arrAngles[i] < 0)){
				}else {
					errorDetect = true;
					break;
				}
				
			}
			
			if (!errorDetect) {
				out("	true");
				return true;
			}
			else {
				out("	false");
				return false;								
			}
		}
		
		private static function detectCircle(form:objectForDetect):Boolean {
			
			out("Check CIRCLE");
			
			if (!processingForm.detectCloseForm(form)) {
				out("	false");
				return false;
			}
			
			out("	step1 true");
			var arrAngles:Array = form.getAngleArray();
			
			if (arrAngles.length < 6) {
				out("	false");
				return false;
			}
			out("	step2 true");
			
			var errorDetect:Boolean = false;
			for (var i:Number = 1; i < arrAngles.length; i++) {
				if(arrAngles[0] < 0 && arrAngles[i] > 0){
					errorDetect = true;
					break;
				}else if(arrAngles[0] > 0 && arrAngles[i] < 0){
					errorDetect = true;
					break;
				}
			}
			
			if (!errorDetect) {
				out("	step3 true");
				
				var angleSumm:Number = 0;
				
				for (i = 0; i < arrAngles.length; i++) {
					angleSumm += arrAngles[i];
				}
				
				if(Math.abs(angleSumm) < settingLogic.minimumAngleSumm){
					out("	true");
					return true;
				}else {
					out("	false: "+angleSumm);
					return false;
				}
			}else {
				out("	false");
				return false;
			}
			
		}
		
		private static function detectSpringle(form:objectForDetect):Boolean {
			
			/*
			if (!processingForm.detectCloseForm(form)) {
				return false;
			}
			*/
			out("Check SPRINGLE");
			var arrAngles:Array = form.getAngleArray();
			
			if (arrAngles.length < 6) {
				out("	false");
				return false;
			}
			
			out("	step1 true");
			var errorDetect:Boolean = false;
			
			for (var i:Number = 1; i < arrAngles.length; i++) {
				if(arrAngles[0] < 0 && arrAngles[i] > 0){
					errorDetect = true;
					break;
				}else if(arrAngles[0] > 0 && arrAngles[i] < 0){
					errorDetect = true;
					break;
				}
			}
			
			if (!errorDetect) {
				
				out("	step2 true");
				
				var angleSumm:Number = 0;
				
				for (i = 0; i < arrAngles.length; i++) {
					angleSumm += Math.abs(arrAngles[i]);
				}
				
				if (angleSumm > settingLogic.minimumAngleSumm) {
					out("	true");
					return true;
				}else {
					out("	false");
					return false;
				}
				
			}else {
				out("	false");
				return false;
			}
		}
		
		private static function detectEight(form:objectForDetect):Boolean {
			
			out("Check NUMBER_8");
			
			if (!processingForm.detectCloseForm(form)) {
				out("	false");
				return false;
			}
			out("	step1 true");
			
			var arrAngles:Array = form.getAngleArray();
			
			if (arrAngles.length < 6) {
				out("	false");
				return false;
			}
			out("	step2 true");
			
			var summAnglePositive:Number = 0;
			var summAngleNegative:Number = 0;
			
			var countChangeSingAngle:Number = 0;
			
			var lastAngle:Number = 0;
			
			for (var i:Number = 0; i < arrAngles.length; i++) {
				
				var deltaAngle:Number = arrAngles[i];
				
				if (deltaAngle > 0) {
					summAnglePositive += deltaAngle;
				}else if (deltaAngle < 0) {
					summAngleNegative += Math.abs(deltaAngle);
				}
				//textOut += "  "+deltaAngle+"\n";
				
				if (lastAngle == 0 ) {
					lastAngle = deltaAngle;
				}if (lastAngle > 0 && deltaAngle < 0) {
					countChangeSingAngle ++;
				}if (lastAngle < 0 && deltaAngle > 0) {
					countChangeSingAngle ++;
				}
				lastAngle = deltaAngle;
				
			}						
			
			if ((summAnglePositive > settingLogic.minSummAngleEight) &&
				(summAnglePositive < settingLogic.maxSummAngleEight) &&
				(summAngleNegative > settingLogic.minSummAngleEight) &&
				(summAngleNegative < settingLogic.maxSummAngleEight) &&
				(countChangeSingAngle >= 1) && (countChangeSingAngle <= 2))
			{
				out("	true");
				return true;
			}else {
				out("	false");
				return false;
			}
			
			
		}
		
		/**
		 * Пихаем в аргументы объект типа objectForDetect с точками по которым шла мышка (смотри описание класса)
		 * желательно перед тем как запихать сюда, пропустить объект через processingObject
		 * и возвращается целое число смотри класс formFactor
		 * @param	form
		 * @return
		 */
		public static function analizeForm(form:objectForDetect):Number {

			if (form.getFullLengthForm() < 5) {
				return formFactor.UNKNOWN;
			}
			
			out("Form closed: "+processingForm.detectCloseForm(form));
			out("Count point: " + form.getPointsArray().length);
			out(form.getAngleStartFinishLine()+"("+form.getAverageAngle()+")");
			
			var formDetected:Number = formFactor.UNKNOWN;
			
			if (detectLine(form)) {
				formDetected = formFactor.LINE;
			}else if (detectTriangle(form)) {
				formDetected = formFactor.TRIANGLE;
			}else if (detectSquare(form)) {
				formDetected = formFactor.SQUARE;
			}else if (detectW(form)) {
				formDetected = formFactor.LETTER_W;
			}else if (detectCircle(form)) {
				formDetected = formFactor.CIRCLE;
			}else if (detectSpringle(form)) {
				formDetected = formFactor.SPRINGLE;
			}else if (detectEight(form)) {
				formDetected = formFactor.NUMBER_8;
			}
			
			return formDetected;
		}
		
	}
	
}